package cn.ytian.scashier;

import java.io.File;
import java.math.BigDecimal;
import java.util.*;

import static cn.ytian.scashier.Config.*;
import static cn.ytian.scashier.Data.SaveOrder;
import static cn.ytian.scashier.Data.readObjectFromFile;
import static cn.ytian.scashier.DocUi.*;
import static cn.ytian.scashier.Language.*;
import static cn.ytian.scashier.YLib.*;
import static cn.ytian.scashier.YMysql.*;

public class Cashier {
    public static HashMap<String, Product> productMap = new HashMap<String, Product>();
    public static List<SalesItem> salesList = new ArrayList<>();
    public static List<SalesItem> salesList2 = new ArrayList<>();
    public static List<Order> orderList = new ArrayList<>();
    static Config conf = Main.conf;

    public static boolean login() {
        YLib.pln(Language.InName);
        String Username = Yin();
        YLib.pln(Language.InPassword);
        String Password = Yin();
        return Username.equals(conf.getUser()) && Password.equals(conf.getPassword());
    }

    public static void loadData() {
        String str = "";
        HashMap<String, Product> tmp = new HashMap<>();
        List<Order> tmp2 = new ArrayList<>();
        if (DataType.equals(Data.DTDat)) {
            tmp = (HashMap<String, Product>) readObjectFromFile(ProductPathDat);
            tmp2 = (List<Order>) readObjectFromFile(OrderItemPathDat);
        }

        if (DataType.equals(Data.DTMysql)) {
            tmp = readProductList();
            tmp2 = getOrderList();
        }

        if (tmp != null)
            if (tmp.size() > 0) {
                productMap = tmp;
                str += productMap_info;
            }

        if (tmp2 != null)
            if (tmp2.size() > 0) {
                orderList = tmp2;
                str += Sales_info;
            }


        if (tmp != null || tmp2 != null)
            pln(Load_yyds, str);


    }

    public static void SaveData(String type) {
        if (DataType.equals(Data.DTDat)) {
            switch (type) {
                case "productMap":
                    Data.writeObjectToFile(productMap, ProductPathDat);
                    break;
                case "salesList":
                    Data.writeObjectToFile(salesList, SalesItemPathDat);
                    break;
                case "OrderList":
                    Data.writeObjectToFile(orderList, OrderItemPathDat);
                    break;
            }
        }
    }

    private static void SaveData(String type, List<Product> nlProduc) {
        if (DataType.equals(Data.DTMysql)) {
            switch (type) {
                case "productMap":
                    type = "product";
                    InLProduct(nlProduc);
                    break;
                case "salesList":
                    type = "sales";
                    break;
            }
        }
    }

    public static void Run() {
        int i = 1;
        int max = 3;
        boolean LoggedIn = false;
        //加载数据
        loadData();
        while (true) {
            if (!LoggedIn) {
                LoggedIn = login();
                cls();
            }

            if (LoggedIn) {
                //登陆成功
                //cls();
                DocUi.LoadMenu();
                if (RunFunc()) return;
            } else {
                i++;
                if (i > max) {
                    YLib.pln(Language.LoginNot);
                    return;
                } else {
                    DocUi.cls();
                    pln(Language.ErrNot, max - i + 1);
                }
            }
        }
    }

    private static boolean RunFunc() {
        pln("\t" + getTime());
        pln("\t\t作者：云天\n");
        pl(RunNbr, Menu_List.size());
        String n = Yin();
        switch (n) {
            case "0":
                pln(Menu_Exit_);
                return true;
            case "1":
                cls();
                sales();
                break;
            case "2":
                cls();
                addProduct();
                break;
            case "3":
                cls();
                SalesRecord();
                break;
            case "4":
                cls();
                SetSystem();
                break;
            default:
                InputLine(Menu_Not_Func);
                cls();
                break;
        }
        return false;
    }

    private static void SalesRecord() {
        String str = "\t%s\t\t%s\t\t%s\t%s\t%s";
        List<String> strList = new ArrayList<>();
        for (Order o : orderList) {
            String oId = o.getOid();
            //String oDate = stampToDate(o.getDateTemp());
            String oDate = o.getDateTemp();
            double oPrice = o.getOPrice();
            String oAdmin = o.getAdmin();
            String oUser = o.getClient();
            String strTmp = String.format(str, oId, oDate, oPrice, oAdmin, oUser);
            strList.add(strTmp);
        }
        LoadList(strList, Sales_Record, "O");
        pl(Sales_Edit, strList.size());
        String n = Yin();
        if (strList.size() == 0) {
            cls();
            return;
        }

        if (n.equals("0")) {
        } else if (strList.size() + 1 >= Integer.parseInt(n)) {
            InfoOrder(n);
        }
        cls();
    }

    static List<SalesItem> getOrSa(String Oid) {
        List<SalesItem> to =  new ArrayList<>();
        for (Order o : orderList) {
            if (o.getOid().equals(Oid)) {
                to = o.getSales();
                return to;
            }
        }
        return to;
    }


    static List<SalesItem> InfoOrderC(String Oid) {

        if (DataType.equals(Data.DTMysql)) {
            return getSalesList(Oid);
        }

        if (DataType.equals(Data.DTDat)) {
            return getOrSa(Oid);
        }

        return null;
    }

    private static void InfoOrder(String Oid) {
        salesList2 = InfoOrderC(Oid);
        cls();
        PLH("S");
        PlnSalesList(salesList2);
        //salesList.clear();
        InputLine(Any);
    }

    private static boolean SetSt_Func() {
        String n = Yin();
        switch (n) {
            case "0":
                return false;
            case "1":
                SetLang();
                break;
        }
        return true;
    }

    private static void SetLang() {
        cls();
        String T = InputStr(Ste_Lang_ln, conf.getLanguage());
        if (Language.load(T)) {
            conf.setLanguage(T);
        } else {
            InputLine(Ste_Lang_NotLang, T);
        }

    }

    private static void SetSystem() {
        boolean xh = true;
        while (xh) {
            LoadMenu(Ste_System_List, Ste_System, MSte_System_Exit);
            pl(RunNbr, Ste_System_List.size());
            xh = SetSt_Func();
            cls();
        }
    }

    private static void PlnProductMap() {
        PLH();
        for (Map.Entry<String, Product> entry : productMap.entrySet()) {
            pln(entry.getValue().toPln());
            // System.err.println("人物hashKey = " + entry.getKey() + ", Value = " + entry.getValue());
        }
    }

    public static double price() {
        double are = 0.00;
        for (SalesItem x : salesList) {
            are += x.getGoodsSubtotal();
        }
        return are;
    }


    private static void PlnSalesListZ() {
        if (salesList.size() > 0) {
            PlnSalesList();
            InputLine(Grand_Total, price());
        } else {
            //InputStr(Grand_Not_Total);
            InputLine(Grand_Not_Total);
        }
    }

    private static void PlnSalesList() {
       PlnSalesList(salesList);
    }

    private static void PlnSalesList(List<SalesItem> sa) {
        int i = 1;
        for (SalesItem x : sa) {
            pln("\t%d%s", i, x.toString());
            i++;
        }
    }

    private static Product FindProductId(String Id) {
        return productMap.get(Id);
    }

    private static void sales() {
        String Ln = "";
        String str = "";
        PlnProductMap();
        while (true) {
            Ln = InputStr(str + Sales_Info);
            str = "";

            if (Ln.equals("S")) {
                //打印显示
                cls();
                PLH("S");
                PlnSalesListZ();

                //保存
                String Oid = String.valueOf(orderList.size() + 1);
                Order OrderTmp = new Order(Oid, salesList, price());
                orderList.add(OrderTmp);
                SaveOrder(OrderTmp);


                //清理痕迹
                salesList = new ArrayList<>();
                cls();
                PlnProductMap();
            } else if (Ln.equals("E")) {
                salesList.clear();
                cls();
                return;
            } else {
                Product PTmp = FindProductId(Ln);
                if (PTmp != null) {
                    int NumberOf = InputInt(Sales_POrderQty, PTmp.getGoodsName());
                    BigDecimal tmpA = BigDecimal.valueOf(PTmp.getGoodsPrice());
                    BigDecimal tmpC = tmpA.multiply(BigDecimal.valueOf(NumberOf));
                    if (NumberOf > 0) {
                        SalesItem temporary = new SalesItem(PTmp.getGoodsID(), PTmp.getGoodsName(), PTmp.getGoodsPrice(), NumberOf, tmpC.doubleValue());
                        salesList.add(temporary);
                        cls();
                        PLH("S");
                        PlnSalesList();
                    } else {
                        InputLine("数量不能小于1(输入任意继续)");
                        cls();
                        PlnProductMap();
                    }
                } else {
//                    InputStr(Sales_Not_Product);
                    str = Sales_Not_Product;
                }
            }
        }
    }

    private static void addProduct() {
        String type = ProductFileReader.type;
        String file = "";
        try {
            while (Objects.equals(type, ProductFileReader.type)) {
                cls();
                pln(Info_addProduct);
                file = Yin();
                if (file.equals("N") || file.equals("n")) {
                    cls();
                    return;
                }
                type = file.substring(file.lastIndexOf(".") + 1);
                switch (type) {
                    case "csv":
                        type = ProductFileReader.csv;
                        break;
                    case "txt":
                        type = ProductFileReader.txt;
                        break;
                    default: {
                        if (InputJBD(Info_addProduct_NotType, "N")) {
                            cls();
                            return;
                        } else {
                            type = ProductFileReader.type;
                        }
                        break;
                    }
                }

                if (!inFileB(file)) {
                    if (InputJBD(Info_addProduct_NotFile, "N")) {
                        cls();
                        return;
                    } else {
                        type = ProductFileReader.type;
                    }
                }
            }

            List<Product> NLProduc = ReadProduct.readProduct(new File(file), type);
            PLH();
            for (Product x : NLProduc) {
                pln(x.toPln());
            }

            if (!InputJBD(Info_addProduct_Determine, "N")) {
                for (Product x : NLProduc) {
                    productMap.put(x.getGoodsID(), x);
                }

                if (DataType.equals(Data.DTDat)) {
                    SaveData("productMap");
                }

                if (DataType.equals(Data.DTMysql)) {
                    SaveData("productMap", NLProduc);
                }
                cls();
            }

        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}
